package dk.aiszone.lang.messer.autosource;

import java.util.ArrayList;
import java.util.List;

import dk.aiszone.lang.autosource.generatorobjects.Class;
import dk.aiszone.lang.autosource.generatorobjects.Declaration;
import dk.aiszone.lang.autosource.generatorobjects.Method;
import dk.aiszone.lang.autosource.generatorobjects.helpers.StringBlock;
import dk.aiszone.lang.autosource.generatorobjects.interfaces.ChildContainer;
import dk.aiszone.lang.autosource.generatorobjects.interfaces.SimpleBlockObject;
import dk.aiszone.lang.messer.autosource.interfaces.ModifiableObject;

/**
 * Extension of the <code>Method</code> used by the <code>SourceMesser</code>.<br>
 * This extension allows for modification of the <code>Method</code> it-self.
 * 
 * @author Ais
 */
public class MesserMethod extends Method implements ModifiableObject, ChildContainer {

    private final int column;
    private List<SimpleBlockObject> modifiedBody;
    private final int row;

    /**
     * Constructor for the <code>MesserMethod</code> class.
     * 
     * @param row
     *            The line of the <code>MesserMethod</code>.
     * @param column
     *            The column of the <code>MesserMethod</code>.
     */
    public MesserMethod(int row, int column) {
        super();
        this.row = row;
        this.column = column;
    }

    /**
     * Constructor for the <code>MesserMethod</code> class.
     * 
     * @param declaration
     *            The <code>Declaration</code> of the <code>Method</code>.
     * @param returnType
     *            The return class of the <code>Method</code>.
     * @param name
     *            The name of the <code>Method</code>.
     * @param row
     *            The line of the <code>MesserMethod</code>.
     * @param column
     *            The column of the <code>MesserMethod</code>.
     */
    public MesserMethod(Declaration declaration, Class returnType, String name, int row, int column) {
        super(declaration, returnType, name);
        this.row = row;
        this.column = column;
    }

    @Override
    public List<SimpleBlockObject> getBodyParts() {
        if (modifiedBody != null) {
            return super.getBodyParts();
        }
        return modifiedBody;
    }

    @Override
    public SimpleBlockObject getChild(int index) {
        return getBodyParts().get(index);
    }

    @Override
    public int getChildCount() {
        return getBodyParts().size();
    }

    @Override
    public int getColumn() {
        return column;
    }

    @Override
    public int getNumberOfSupportedModifications() {
        if ("equals".equals(getName())) {
            return 2;
        }
        if ("hashCode".equals(getName())) {
            return 1;
        }
        // TODO: CompareTo....
        return 0;
    }

    @Override
    public int getRow() {
        return row;
    }

    @Override
    public boolean isModifiable() {
        if ("equals".equals(getName())) {
            return true;
        }
        if ("hashCode".equals(getName())) {
            return true;
        }
        // TODO: CompareTo....
        return false;
    }

    @Override
    public void modify(int index) {
        if ("equals".equals(getName())) {
            handleEqualsMethodTransformation(index);
        } else if ("hashCode".equals(getName())) {
            handleHashCodeMethodTransformation();
        }
    }

    @Override
    public void revert() {
        modifiedBody = null;
    }

    private void handleEqualsMethodTransformation(int index) {
        modifiedBody = new ArrayList<SimpleBlockObject>();
        if (index == 0) {
            modifiedBody.add(new StringBlock("return false;"));
        } else if (index == 1) {
            modifiedBody.add(new StringBlock("return true;"));
        }
    }

    private void handleHashCodeMethodTransformation() {
        modifiedBody = new ArrayList<SimpleBlockObject>();
        modifiedBody.add(new StringBlock("return 0;"));
    }
}